import { memo, useEffect, useRef, useState } from 'react';
import type { ReactNode, FC } from 'react';
import { VoiceRangeWrapper } from './style';

interface IProps {
  children?: ReactNode;
  className?: string;
}

const MAX_HEIGHT = 93; // 最大高度

const VoiceRange: FC<IProps> = (props) => {
  const { className } = props;
  const [volume, setVolume] = useState(93);
  const [isDragging, setIsDragging] = useState(false);

  const rangeRef = useRef<HTMLDivElement | null>(null);

  // 根据鼠标位置计算音量
  const getVolumeByY = (clientY: number) => {
    const rect = rangeRef.current!.getBoundingClientRect();
    let offset = clientY - rect.top;
    // 限制在 0~MAX_HEIGHT 之间
    offset = Math.max(0, Math.min(MAX_HEIGHT, offset));
    // 计算百分比
    return MAX_HEIGHT - offset;
  };

  // 点击改变音量
  const handleVoiceClick = (e: React.MouseEvent) => {
    if (!rangeRef.current) return;
    const newVolume = getVolumeByY(e.clientY);
    setVolume(newVolume);
  };

  // 按下拖拽
  const handleMouseDown = (e: React.MouseEvent<HTMLSpanElement, MouseEvent>) => {
    e.preventDefault();
    setIsDragging(true);
  };

  // 拖拽过程
  useEffect(() => {
    if (!isDragging) return;

    const handleMove = (e: MouseEvent) => {
      if (!rangeRef.current) return;
      const newVolume = getVolumeByY(e.clientY);
      setVolume(newVolume);
    };
    const handleUp = () => setIsDragging(false);

    document.addEventListener('mousemove', handleMove);
    document.addEventListener('mouseup', handleUp);

    return () => {
      document.removeEventListener('mousemove', handleMove);
      document.removeEventListener('mouseup', handleUp);
    };
    // eslint-disable-next-line
  }, [isDragging]);

  return (
    <VoiceRangeWrapper className={className} onClick={handleVoiceClick}>
      <div className="v-bg sprite_player"></div>
      <div className="range" ref={rangeRef}>
        <div className="item sprite_player" style={{ height: `${volume}px` }}></div>
        <span
          className="btn sprite_icon"
          onMouseDown={handleMouseDown}
          style={{ top: `${MAX_HEIGHT - volume}px` }}
        ></span>
      </div>
    </VoiceRangeWrapper>
  );
};

export default memo(VoiceRange);
